from datetime import datetime
from decimal import Decimal
from typing import Optional

from pydantic import BaseModel, ConfigDict, EmailStr, Field

from app.core.constants import BoolEnum, GenderType


# ============
# 基础模型
# ============
class UserBase(BaseModel):
    """用户基础模型"""

    username: str = Field(..., min_length=3, max_length=32, description="用户名")
    email: Optional[EmailStr] = Field(None, max_length=20, description="邮箱")
    phone: Optional[str] = Field(None, max_length=20, description="联系电话")

    is_active: BoolEnum = Field(default=BoolEnum.TRUE, description="是否激活")
    is_staff: BoolEnum = Field(default=BoolEnum.FALSE, description="是否为员工")
    is_superuser: BoolEnum = Field(default=BoolEnum.FALSE, description="是否为超级用户")


class UserProfileBase(BaseModel):
    """用户档案基础模型"""

    nickname: Optional[str] = Field(None, max_length=255, description="昵称")
    avatar: Optional[str] = Field(None, max_length=255, description="头像")
    gender: GenderType = Field(default=GenderType.NO, description="性别")
    birthday: Optional[datetime] = Field(None, description="出生年月")
    introduction: Optional[str] = Field(None, max_length=200, description="个人介绍")

    model_config = ConfigDict(from_attributes=True)


# ============
# CRUD模型
# ============
class UserProfile(UserProfileBase):
    """用户档案完整模型"""

    id: int = Field(..., description="档案ID")
    user_id: int = Field(..., description="用户ID")
    created_at: Optional[datetime] = Field(None, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")


# 命名规则, [模型][动作][response/request]


class UserCreateRequest(UserBase):
    """用户创建请求模型"""

    profile: Optional[UserProfileBase] = Field(None, description="用户档案")


class UserCreateResponse(UserBase):
    """用户创建响应模型"""

    id: int = Field(..., description="用户ID")
    last_login: Optional[datetime] = Field(None, description="最后登录时间")
    date_joined: datetime = Field(..., description="注册时间")
    profile: Optional[UserProfileBase] = Field(None, description="用户档案")

    model_config = ConfigDict(from_attributes=True)


class UserUpdateRequest(UserBase):
    """用户更新请求模型"""

    profile: Optional[UserProfileBase] = Field(None, description="用户档案")


class UserUpdateResponse(UserBase):
    """用户更新响应模型"""

    id: int = Field(..., description="用户ID")
    last_login: Optional[datetime] = Field(None, description="最后登录时间")
    date_joined: datetime = Field(..., description="注册时间")
    profile: Optional[UserProfileBase] = Field(None, description="用户档案")

    model_config = ConfigDict(from_attributes=True)


class UserDetailResponse(UserBase):
    """用户详情响应模型"""

    id: int = Field(..., description="用户ID")
    last_login: Optional[datetime] = Field(None, description="最后登录时间")
    points: Optional[int] = Field(None, description="积分")
    balance: Optional[Decimal] = Field(None, description="余额")
    date_joined: datetime = Field(..., description="注册时间")
    profile: Optional[UserProfileBase] = Field(None, description="用户档案")

    model_config = ConfigDict(from_attributes=True)


class UserDeleteResponse(UserBase):
    """用户删除响应模型"""

    id: int = Field(..., description="用户ID")
    last_login: Optional[datetime] = Field(None, description="最后登录时间")
    date_joined: datetime = Field(..., description="注册时间")
    profile: Optional[UserProfileBase] = Field(None, description="用户档案")

    model_config = ConfigDict(from_attributes=True)


class UserFilters(BaseModel):
    """用户筛选条件"""

    username: Optional[str] = Field(None, description="用户名")
    email: Optional[str] = Field(None, description="邮箱")
    phone: Optional[str] = Field(None, description="联系电话")
    is_active: Optional[BoolEnum] = Field(None, description="是否激活")
    is_staff: Optional[BoolEnum] = Field(None, description="是否为员工")
    is_superuser: Optional[BoolEnum] = Field(None, description="是否为超级用户")


class PasswordChangeRequest(BaseModel):
    """密码修改请求模型"""

    old_password: str = Field(..., min_length=6, max_length=32, description="旧密码")
    new_password: str = Field(..., min_length=6, max_length=32, description="新密码")
    re_password: str = Field(..., min_length=6, max_length=32, description="确认密码")

    model_config = ConfigDict(from_attributes=True)


class BalanceRechargeRequest(BaseModel):
    """余额充值请求模型"""

    amount: Decimal = Field(..., gt=0, description="充值金额")

    model_config = ConfigDict(from_attributes=True)


class PointsRechargeRequest(BaseModel):
    """积分充值请求模型"""

    points: int = Field(..., gt=0, description="充值积分")

    model_config = ConfigDict(from_attributes=True)
